package com.skivingcloud.common.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 文件下载工具类
 * @author hushouquan
 *
 */
public class DownloadUtils {
	private static Logger logger = LoggerFactory.getLogger(DownloadUtils.class);
	public static void download(String fileName,String filepath, HttpServletRequest request, HttpServletResponse response)
				throws Exception {
	
			response.setContentType("text/html;charset=utf-8");
			request.setCharacterEncoding("UTF-8");
			java.io.BufferedInputStream bis = null;
			java.io.BufferedOutputStream bos = null;
	
			String ctxPath = request.getSession().getServletContext().getRealPath("/") +filepath;
			try {
				File file = new File(ctxPath);
				if(!file.exists())
					logger.warn("download agent is error ! messages --->> "+ctxPath+" is not exists !");
				response.setContentType("application/x-msdownload;");
				response.setHeader("Content-disposition",
						"attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
				response.setHeader("Content-Length", String.valueOf(file.length()));
				bis = new BufferedInputStream(new FileInputStream(ctxPath));
				bos = new BufferedOutputStream(response.getOutputStream());
				byte[] buff = new byte[2048];
				int bytesRead;
				while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
					bos.write(buff, 0, bytesRead);
				}
			} catch (Exception e) {
				logger.warn("download agent is error ! messages --->> "+e.fillInStackTrace());
			} finally {
				if (bis != null)
					bis.close();
				if (bos != null)
					bos.close();
			}
		}
	
	/**
	 * 根据路径下载文件
	 * @param response
	 * @param path 文件全路径
	 * @param fileName 下载时候的文件名
	 * @throws IOException
	 */
	public static void fileDownload(HttpServletResponse response, String path, String fileName) throws IOException {
		OutputStream out = response.getOutputStream();
		try {
			response.setContentType("application/octet-stream;charset=UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
			FileInputStream inStream = new FileInputStream(path);
			byte[] buf = new byte[4096];
			int readLength;
			while (((readLength = inStream.read(buf)) != -1)) {
				out.write(buf, 0, readLength);
			}
			inStream.close();
		} catch (IOException e1) {
			logger.error("io stream error,error:" + e1.getMessage(), e1);
			throw e1;
		} finally {
			IOUtils.closeQuietly(out);
		}
	}
	
	/**
	 * 根据路径下载文件，针对火狐做特殊处理
	 * @param response
	 * @param path 文件全路径
	 * @param fileName 下载时候的文件名
	 * @throws IOException
	 */
	public static void fileDownload(HttpServletRequest request,HttpServletResponse response, String path, String fileName) throws IOException {
		OutputStream out = response.getOutputStream();
		try {
			response.setContentType("application/octet-stream;charset=UTF-8");
			String filenamedisplay = java.net.URLEncoder.encode(fileName, "UTF-8");  
	        if ("FF".equals(getBrowser(request))) {  
	            // 针对火狐浏览器处理方式不一样了  
	            filenamedisplay = new String(fileName.getBytes("UTF-8"), "iso-8859-1");  
	        }  
	        response.setHeader("Content-Disposition", "attachment;filename=" + filenamedisplay);  
			//response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
			FileInputStream inStream = new FileInputStream(path);
			byte[] buf = new byte[4096];
			int readLength;
			while (((readLength = inStream.read(buf)) != -1)) {
				out.write(buf, 0, readLength);
			}
			inStream.close();
		} catch (IOException e1) {
			logger.error("io stream error,error:" + e1.getMessage(), e1);
			throw e1;
		} finally {
			IOUtils.closeQuietly(out);
		}
	}
	
	/**
	 * 从输入流中下载文件
	 * @param response
	 * @param inStream 输入流
	 * @param fileName 下载时显示的文件名
	 * @throws IOException
	 */
	public static void fileInputStreamDownload(HttpServletResponse response, FileInputStream inStream, String fileName) throws IOException {
		OutputStream out = response.getOutputStream();
		try {
			response.setContentType("application/octet-stream;charset=UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));//.zip
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
			byte[] buf = new byte[4096];
			int readLength;
			while (((readLength = inStream.read(buf)) != -1)) {
				out.write(buf, 0, readLength);
			}
		} catch (IOException e1) {
			logger.error("io stream error,error:" + e1.getMessage(), e1);
			throw e1;
		} finally {
			out.close();
		}
	}

	/**
	 * 直接用浏览器调用已知程序打开
	 * @param response
	 * @param path 文件全路径
	 * @param fileName 文件名
	 * @throws IOException
	 */
	public static void fileOpen(HttpServletResponse response, String path, String fileName)  throws IOException {
		OutputStream out = response.getOutputStream();
		try {
			response.setContentType("application/octet-stream;charset=UTF-8");
			response.setHeader("Content-Disposition", "filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));//.zip
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
			FileInputStream inStream = new FileInputStream(path);
			byte[] buf = new byte[4096];
			int readLength;
			while (((readLength = inStream.read(buf)) != -1)) {
				out.write(buf, 0, readLength);
			}
			inStream.close();
		} catch (IOException e1) {
			logger.error("io stream error,error:" + e1.getMessage(), e1);
		} finally {
			IOUtils.closeQuietly(out);
		}
		
	}
	
	/**
	 * 读取某个文件夹下的所有文件
	 */
	public static List<File> readfile(String filepath) throws FileNotFoundException, IOException {
		File dir = new File(filepath);
		String[] filter = null;// {"zip","rar"};
		List<File> files = new ArrayList<File>();
		if (dir.exists()) {
			files = (List) FileUtils.listFiles(dir, filter, true);
		}
		return files;
	}
	
	/**
	 * 读取某个文件夹下的所有文件
	 */
	public static File[] readfileArray(String filepath) throws FileNotFoundException, IOException {
		File dir = new File(filepath);
		String[] filter = null;// {"zip","rar"};
		List<File> files = new ArrayList<File>();
		if (dir.exists()) {
			files = (List) FileUtils.listFiles(dir, filter, true);
		}
		File[] filenews = new File[files.size()];
		for(int i = 0; i < files.size(); i++){
			File file = files.get(i);
			filenews[i] = file;
		}
		return filenews;
	}
	/**
	 * 删除某个文件夹下的所有文件
	 */
	public static boolean deletefile(String delpaths) throws FileNotFoundException, IOException {
		String[] tmpPath = delpaths.split(";");
		for (int i = 0; i < tmpPath.length; i++) {
			File file = new File(tmpPath[i]);
			if (file.exists())
				file.delete();
		}
		return true;
	}
	/**
	 * 删除某个文件夹下的所有文件夹
	 */

	public static boolean deletefolder(String delpaths) throws FileNotFoundException, IOException {
		String[] tmpPath = delpaths.split(";");
		for (int i = 0; i < tmpPath.length; i++) {
			File dir = new File(tmpPath[i]);
			String[] filter = null;// {"zip","rar"};
			if (dir.exists()) {
				List files = (List) FileUtils.listFiles(dir, filter, true);
				for (Iterator iterator = files.iterator(); iterator.hasNext();) {
					File file = (File) iterator.next();
					file.deleteOnExit();
				}
			}
		}
		return true;
	}
	
	/**
     * 递归删除目录下的所有文件及子目录下所有文件
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     *                 If a deletion fails, the method stops attempting to
     *                 delete and returns "false".
     */
    public static boolean deleteDir(File dir, boolean ispar) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            //递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]), false);
                if (!success) {
                    return false;
                }
            }
        }
        if(!ispar){
        	// 目录此时为空，可以删除
        	return dir.delete();
        }else{
        	return true;
        }
    }

 // 以下为服务器端判断客户端浏览器类型的方法  
    private static String getBrowser(HttpServletRequest request) {  
        String UserAgent = request.getHeader("USER-AGENT").toLowerCase();  
        if (UserAgent != null) {  
            if (UserAgent.indexOf("msie") >= 0)  
                return "IE";  
            if (UserAgent.indexOf("firefox") >= 0)  
                return "FF";  
            if (UserAgent.indexOf("safari") >= 0)  
                return "SF";  
            if(UserAgent.indexOf("mozilla") >= 0)
            	return "Chrome";
        }  
        return null;  
    }  
    
}

